home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / utility / utilcli / abortpkt.lzh / AbortPkt / jumptable.c < prev    next >
C/C++ Source or Header  |  1996-11-06  |  5KB  |  168 lines

  1. /*
  2.     InstallWedge, RemoveWedge and GetJumpTable were taken from
  3.     UnixDirsII (by Martin W. Scott, mws@castle.ed.ac.uk)
  4.     They are based on a method used in ISpy, a CBM-provided AmigaMail example.
  5. */
  6.  
  7. #include <dos/dos.h>
  8. #include <exec/types.h>
  9. #include <exec/execbase.h>
  10. #include <exec/memory.h>
  11. #include <exec/semaphores.h>
  12. #include <string.h>
  13. #include <proto/dos.h>
  14. #include <proto/exec.h>
  15.  
  16. /* The name this JumpTable/Semaphore will get. */
  17. UBYTE *JTName = "AbortPktPatch-JT";
  18.  
  19. #include "jumptable.h"
  20.  
  21. DECLARE_PATCH (AbortPkt)
  22.  
  23. struct LVOTable LVOArray[NUMBEROFFUNCTIONS] = {
  24. { &LVOAbortPkt, (struct Library *) &DOSBase, &AbortPktO, &AbortPktStub }
  25.   };
  26.  
  27. char *
  28. InstallWedge (VOID)
  29. {
  30.   struct JumpTable *jumptable;
  31.   ULONG *addressptr;
  32.   UCOUNT i, j;
  33.   char *errstr;
  34.  
  35.   Forbid ();
  36.  
  37.   /* Get pointer to JumpTable. Create it if necessary */
  38.   if (jumptable = GetJumpTable (JTName))
  39.   {
  40.     /* Try to get exclusive lock on semaphore, in case it already existed. */
  41.     if (AttemptSemaphore ((struct SignalSemaphore *) jumptable))
  42.     {
  43.       /* Make sure nobody else has function addresses in the jumptable */
  44.       if (jumptable->jt_Owner == NULL)
  45.       {
  46.     jumptable->jt_Owner = FindTask (0);
  47.     /* Don't want to disable any longer than necessary */
  48.     Disable ();
  49.  
  50.     for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  51.     {
  52.       /* Replace addresses in the jumptable with my own. */
  53.       addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  54.       (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
  55.       *addressptr = (ULONG) LVOArray[j].lt_newFunction;
  56.     }
  57.     Enable ();
  58.       } 
  59.       else
  60.     errstr = "Already running.\n";
  61.       ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
  62.     }
  63.     else
  64.       errstr = "Can't lock table.\n";
  65.   }
  66.   else
  67.     errstr = "Can't create jumptable\n";
  68.   Permit ();
  69.  
  70.   return jumptable ? NULL : errstr;
  71. }
  72.  
  73. BOOL
  74. RemoveWedge (VOID)
  75. {
  76.   struct JumpTable *jumptable;
  77.   ULONG *addressptr;
  78.   UCOUNT i, j;
  79.  
  80.   Forbid ();
  81.  
  82.   if (jumptable = GetJumpTable (JTName))
  83.   {
  84.     /* Check if this task owns this jumptable */
  85.     if (jumptable->jt_Owner == FindTask (0))
  86.     {
  87.       /* Get the semaphore exclusively.
  88.        * Depending on what got SetFunction ()'ed this could take some time.
  89.        * Also note that shared locks are used to indicate the code is
  90.        * being executed and that shared locks can jump ahead of queue'ed
  91.        * exclusive locks, adding to the waittime.
  92.        */
  93.       ObtainSemaphore ((struct SignalSemaphore *) jumptable);
  94.  
  95.       Disable ();
  96.  
  97.       /* Restore old pointers in jumptable */
  98.  
  99.       for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  100.       {
  101.         addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  102.         *addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
  103.       }
  104.       Enable ();
  105.  
  106.       jumptable->jt_Owner = NULL;
  107.       ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
  108.     }
  109.   }
  110.   Permit ();
  111.  
  112.   return (TRUE);
  113. }
  114.  
  115. struct JumpTable *
  116. GetJumpTable (UBYTE * name)
  117. {
  118.   struct JumpTable *jumptable;
  119.   ULONG *addressptr;
  120.   UWORD *jmpinstr;
  121.   UBYTE *jtname;
  122.   UCOUNT i, j;
  123.  
  124.   /* Not really necessary to forbid again, just to indicate that I don't
  125.    * want another task to create the semaphore while I'm trying to do the
  126.    * same. Here GetJumpTable () is only called from InstallWedge (), so it
  127.    * will just bump the forbid count.
  128.    */
  129.   Forbid ();
  130.  
  131.   if (!(jumptable = (struct JumpTable *) FindSemaphore (name)))
  132.   {
  133.     if (jumptable = AllocMem (sizeof (struct JumpTable), MEMF_PUBLIC | MEMF_CLEAR))
  134.     {
  135.       if (jtname = AllocMem (strlen (name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
  136.       {
  137.         for (i = 0, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  138.         {
  139.           jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
  140.           *jmpinstr = 0x4EF9;
  141.  
  142.           addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
  143.           *addressptr = (ULONG) SetFunction (
  144.              (struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
  145.              LVOArray[j].lt_LVO,
  146.              (VOID *) ((UBYTE *) jumptable->jt_Function + i)
  147.           );
  148.         }
  149.         jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
  150.         strcpy (jtname, name);
  151.         jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
  152.         AddSemaphore ((struct SignalSemaphore *) jumptable);
  153.       }
  154.       else {
  155.         FreeMem (jumptable, sizeof (struct JumpTable));
  156.         jumptable = NULL;
  157.       }
  158.     }
  159.   }
  160.   Permit ();
  161.  
  162.   /* If succeeded, you now have a jumptable which entries point to the original
  163.    * library functions. If another task SetFunction ()'ed one or more of those
  164.    * already, that task can never go away anymore.
  165.    */
  166.   return (jumptable);
  167. }
  168.